//   @Name    : startup_name/ text_number_limit_formatter
//   @author  : simon
//   @date    : 2020/7/28 9:25 PM
//   @desc    : 输入控制，小数点前几位，小数点后几位。
//   注意：使用这个inputFormatters之后，只能输入数字，不能输入文字。
//  2023.10.18 优化
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';

//数字输入的精确控制。
class CaiTextNumberLimitFormatter extends TextInputFormatter {
  //小数点前
  final int beforeDecimalPoint;
  //小数点后
  final int afterDecimalPoint;

  CaiTextNumberLimitFormatter(this.beforeDecimalPoint, this.afterDecimalPoint);

  RegExp exp = RegExp("[0-9.]");
  static const String pointer = ".";
  static const String zero = "0";

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    ///输入完全删除
    if (newValue.text.isEmpty) {
      return const TextEditingValue();
    }

    //只允许输入数字和小数点
    if (!exp.hasMatch(newValue.text)) {
      return oldValue;
    }

    ///包含小数点的情况
    if (newValue.text.contains(pointer)) {
      //精度为0，即不含小数
      if (afterDecimalPoint == 0) {
        return oldValue;
      }

      ///包含多个小数
      if (newValue.text.indexOf(pointer) !=
          newValue.text.lastIndexOf(pointer)) {
        return oldValue;
      }
      String input = newValue.text;
      int index = input.indexOf(pointer);

      ///小数点前位数
      int lengthBeforePointer = input.substring(0, index).length;

      ///整数部分大于约定长度
      if (lengthBeforePointer > beforeDecimalPoint) {
        return oldValue;
      }

      ///小数点后位数
      int lengthAfterPointer = input.substring(index, input.length).length - 1;
      if (kDebugMode) {
        print('小数后位数$lengthAfterPointer');
      }

      ///小数位大于精度
      if (lengthAfterPointer > afterDecimalPoint) {
        return oldValue;
      }
    } else if (
        //以点开头
        newValue.text.startsWith(pointer) ||
            //如果第1位为0，并且长度大于1，排除00,01-09所有非法输入
            (newValue.text.startsWith(zero) && newValue.text.length > 1) ||
            //如果整数长度超过约定长度
            newValue.text.length > beforeDecimalPoint) {
      return oldValue;
    }
    return newValue;
  }
}
